home *** CD-ROM | disk | FTP | other *** search
- Subject: v12i031: C News alpha release, Part06/14
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rs@uunet.UU.NET
-
- Submitted-by: utzoo!henry (Henry Spencer)
- Posting-number: Volume 12, Issue 31
- Archive-name: cnews/part06
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 6 (of 14)."
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'batch/sendbatches' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'batch/sendbatches'\"
- else
- echo shar: Extracting \"'batch/sendbatches'\" \(3153 characters\)
- sed "s/^X//" >'batch/sendbatches' <<'END_OF_FILE'
- X# Master batching control.
- XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}
- XNEWSCTL=${NEWSCTL-/usr/lib/news}
- XNEWSARTS=${NEWSARTS-/usr/spool/news}
- XPATH=$NEWSCTL/batch:$NEWSBIN/batch:/bin:/usr/bin ; export PATH
- Xorigpath=$PATH
- XNEWSUMASK=${NEWSUMASK-002}
- Xumask $NEWSUMASK
- X
- X# Locking.
- Xcd $NEWSCTL
- Xecho $$ >LOCKbatch$$
- Xif ln LOCKbatch$$ LOCKbatch >/dev/null 2>/dev/null
- Xthen
- X rm LOCKbatch$$
- X trap "rm -f $NEWSCTL/LOCKbatch ; exit" 0 1 2 3 15
- Xelse
- X rm LOCKbatch$$
- X exit 0
- Xfi
- X
- X# Go to the heart of the matter.
- Xcd $NEWSCTL/batch
- X
- X# Determine what systems are being requested, in what order.
- Xcase $#
- Xin
- X 0)
- X ls | sed -n '/^b\./s///p' | sort >/tmp/nb$$sy
- X if test -r sites
- X then
- X egrep -v '^[ ]*(#|$)' sites | awk '{ print $1, NR }' |
- X sort >/tmp/nb$$o
- X join -a1 -e 9999 -o 1.1 2.2 /tmp/nb$$sy /tmp/nb$$o >/tmp/nb$$t
- X sort +1 -n /tmp/nb$$t | awk '{ print $1 }' >/tmp/nb$$sy
- X fi
- X syses=`cat /tmp/nb$$sy`
- X rm -f /tmp/nb$$sy /tmp/nb$$o /tmp/nb$$t
- X ;;
- X
- X *)
- X case "$1"
- X in
- X -c)
- X if test ! -r sites
- X then
- X echo "$0: -c illegal in absence of sites file" >&2
- X exit 2
- X fi
- X shift
- X syses=`for class in $*
- X do
- X egrep -v '^[ ]*(#|$)' sites |
- X egrep "[, ]$class(\$|[, ])" |
- X awk '{print $1}'
- X done`
- X ;;
- X
- X *)
- X syses="$*"
- X ;;
- X esac
- X ;;
- Xesac
- X
- X# Start up logging.
- Xmv $NEWSCTL/batchlog.o $NEWSCTL/batchlog.oo
- Xmv $NEWSCTL/batchlog $NEWSCTL/batchlog.o
- Xdate >$NEWSCTL/batchlog
- X
- X# Run through them.
- Xfor sys in $syses
- Xdo
- X # Move into his directory, include it in search path.
- X here=$NEWSCTL/batch/b.$sys
- X if test ! -d $here
- X then
- X echo "$0: cannot find batch directory for site $sys" >&2
- X continue
- X fi
- X cd $here
- X PATH=$here:$origpath ; export PATH
- X NEWSSITE=$sys ; export NEWSSITE # For site-specific programs.
- X
- X # Is there anything to do?
- X files=`echo togo*`
- X if test "$files" = 'togo*' || test "$files" = "togo" -a ! -s togo
- X then
- X continue # no
- X fi
- X
- X # How many batches should we send?
- X outstand=`queuelen $sys`
- X limit=`queuemax`
- X nbatch=`expr $limit - $outstand`
- X batchsize=`batchsize`
- X roomfor=`roomfor $batchsize`
- X if test " $nbatch" -gt " $roomfor"
- X then
- X nbatch=$roomfor
- X fi
- X
- X # If not allowed to send, remember reason.
- X status='batches flowing'
- X if test " $nbatch" -le 0
- X then
- X if test " $roomfor" -le 0
- X then
- X status='disk too full for batching'
- X else
- X status='queue full'
- X fi
- X fi
- X
- X # Try sending some.
- X while test " $nbatch" -gt 0
- X do
- X # Does he have batches prepared already?
- X if test "`echo togo.*`" = 'togo.*'
- X then
- X # No -- need some more batches.
- X if test ! -s togo
- X then
- X break # Nothing left to do.
- X fi
- X batchprep $batchsize
- X fi
- X
- X # Send some batches.
- X them=`ls | egrep '^togo\.' | sed "${nbatch}q"`
- X for f in $them
- X do
- X batchmake -d $NEWSARTS $f | batchmunch |
- X batchxmit $sys
- X rm $f
- X done
- X ndone=`echo $them | wc -w`
- X nbatch=`expr $nbatch - $ndone`
- X
- X # Recheck the space -- it can fall for other reasons.
- X roomfor=`roomfor $batchsize`
- X if test " $nbatch" -gt " $roomfor"
- X then
- X nbatch=$roomfor
- X fi
- X done
- X
- X # Report status, if appropriate.
- X nart=`cat togo* | wc -l | awk '{print $1}'`
- X if test " $nart" -gt 0
- X then
- X echo "$sys backlog $nart ($status)" >>$NEWSCTL/batchlog
- X fi
- Xdone
- END_OF_FILE
- if test 3153 -ne `wc -c <'batch/sendbatches'`; then
- echo shar: \"'batch/sendbatches'\" unpacked with wrong size!
- fi
- # end of 'batch/sendbatches'
- fi
- if test -f 'expire/expire.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'expire/expire.1'\"
- else
- echo shar: Extracting \"'expire/expire.1'\" \(3912 characters\)
- sed "s/^X//" >'expire/expire.1' <<'END_OF_FILE'
- X.TH EXPIRE 1M local
- X.DA 3 Oct 1987
- X.SH NAME
- Xexpire \- expire old news
- X.SH SYNOPSIS
- X.B /usr/lib/newsbin/expire/expire
- X[
- X.B \-a
- Xarchdir
- X] [
- X.B \-p
- X] [
- X.B \-o
- X]
- X[ controlfile ]
- X.SH DESCRIPTION
- X.I Expire
- Xexpires old news, removing it from the current-news directories and
- X(if asked to) archiving it elsewhere.
- XIt updates news's
- X.I history
- Xfile to match.
- X.I Expire
- Xshould be run nightly.
- X.PP
- X.IR Expire 's
- Xoperations are controlled by a control file
- X(which can be named or supplied on standard input),
- Xwhich is not optional\(emthere is no default behavior.
- XEach line of the control file should have four white-space-separated
- Xfields, as follows.
- X.PP
- XThe first field is one or more newsgroups,
- Xseparated by commas (no spaces!);
- Xpartial specifications are acceptable (e.g. `comp' specifies all groups
- Xwith that prefix).
- X.PP
- XThe second field is one letter, `m', `u', or `x', specifying that the line
- Xapplies only to moderated groups, only to unmoderated groups, or to both,
- Xrespectively.
- X.PP
- XThe third field specifies the expiry period in days.
- XThe most general form is three numbers separated by dashes.
- XThe units are days; decimal fractions are permitted.
- XThe first number gives the retention period:
- Xhow long must pass after an article's arrival before it is a candidate
- Xfor expiry.
- XThe third number gives the purge date:
- Xhow long must pass after arrival
- Xbefore the article will be expired unconditionally.
- XThe middle number gives the default expiry date:
- Xhow long after an article's arrival it is expired by default.
- XAn explicit expiry date in the article will override the default expiry
- Xdate but not the retention period or the purge date.
- XIf the field contains only two numbers with a dash separating them,
- Xthe retention period defaults to 0.
- XIf the field contains only a number, the retention period defaults to 0
- Xand the purge date defaults to `never'.
- X.PP
- XThe fourth field is an archiving directory,
- Xor `@' which indicates that the default archiving directory (see \fB\-a\fR)
- Xshould be used,
- Xor `\-' which suppresses archiving.
- X.PP
- XThe first line of the control file which applies to a given article is
- Xused to control its expiry.
- XIt is an error for no line to apply;
- Xthe last line should be something like `all\ x\ 14\ \-'
- Xto ensure that at least one line is always applicable.
- XCross-posted articles are treated as if they were independently posted
- Xto each group.
- X.PP
- XThe
- X.B \-a
- Xoption specifies a default archiving directory;
- Xif no default is given, it is illegal for the control file to contain
- Xany `@' archive-directory fields.
- X.PP
- X.I Expire
- Xcreates subdirectories under an archiving directory automatically,
- Xbut will not create the archiving directory itself.
- XArchiving directories must be given as full pathnames.
- X.PP
- XThe
- X.B \-p
- Xoption causes an `index' line to be printed for each archived article,
- Xcontaining its pathname, message ID, date received, and `Subject:' line.
- XThe
- X.B \-o
- Xoption tells
- X.I expire
- Xto use the obsolete 4-field history-file format used by early variants
- Xof C news.
- X.PP
- X\fIExpire\fR and its auxiliaries recognize the standard
- Xenvironment variables \fB$\&NEWSARTS\fR,
- X\fB$\&NEWSCTL\fR, \fB$\&NEWSBIN\fR, and \fB$NEWSUMASK\fR
- Xwhich indicate, respectively, non-default locations
- Xfor news articles, news control files, and news programs,
- Xand a non-default \fIumask\fR (see \fIumask\fR(2)) for file creation
- X(the default \fIumask\fR is 002).
- X.SH FILES
- X.ta 4c
- X.nf
- X\fIlibrary\fR/history history file
- X\fIlibrary\fR/history.pag \fIdbm\fR database for history file
- X\fIlibrary\fR/history.dir \fIdbm\fR database for history file
- X.SH SEE ALSO
- Xinews(1)
- X.SH HISTORY
- XWritten at U of Toronto by Henry Spencer, with contributions by Geoff Collyer.
- X.SH BUGS
- XArchiving is always done by copying, never by linking.
- XThis has the side effect that cross-posted articles are archived as
- Xseveral independent copies.
- X.PP
- XThe
- X.B \-p
- Xsubject-finder botches continued `Subject:' lines, although
- Xthese are rare.
- END_OF_FILE
- if test 3912 -ne `wc -c <'expire/expire.1'`; then
- echo shar: \"'expire/expire.1'\" unpacked with wrong size!
- fi
- # end of 'expire/expire.1'
- fi
- if test -f 'expire/ns.p' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'expire/ns.p'\"
- else
- echo shar: Extracting \"'expire/ns.p'\" \(3614 characters\)
- sed "s/^X//" >'expire/ns.p' <<'END_OF_FILE'
- Xmkdir ns ns/foo ns/bar ns/bletch
- Xmkdir ns/foo/one ns/foo/two ns/foo/three
- Xmkdir ns/bar/one ns/bar/two ns/bar/five
- Xmkdir ns/bletch/one ns/bletch/four ns/bletch/six
- X
- X# The "should-expire" headers are for checking afterward.
- X
- X# In foo/one, run through the simple cases of dates before and after
- X# expiry dates. Also where the Subject: line is in the article.
- Xoldfile 11 ns/foo/one/95 <<!
- XMessage-ID: <aya.foo/one/95>
- XShould-expire: yes
- XSubject: foo one/95
- X
- Xbody
- X!
- Xoldfile 10 ns/foo/one/96 <<!
- XMessage-ID: <bn.foo/one/96>
- XShould-expire: no
- XSubject: foo one/96
- X
- Xbody
- X!
- Xoldfile 11 ns/foo/one/97 <<!
- XMessage-ID: <cya.foo/one/97>
- XShould-expire: yes
- XSubject: foo one/97
- XExpires: `olddate 1`
- X
- Xbody
- X!
- Xoldfile 10 ns/foo/one/98 <<!
- XSubject: foo one/98
- XMessage-ID: <dn.foo/one/98>
- XShould-expire: no
- XExpires: `olddate -1`
- X
- Xbody
- X!
- Xoldfile 11 ns/foo/one/99 <<!
- XMessage-ID: <en.foo/one/99>
- XShould-expire: no
- XExpires: `olddate -1`
- XSubject: foo one/99
- XMumble: frotz
- X
- Xbody
- X!
- Xoldfile 10 ns/foo/one/100 <<!
- XSubject: foo one/100
- XMessage-ID: <fya.foo/one/100>
- XShould-expire: yes
- XExpires: `olddate 1`
- X
- Xbody
- X!
- X
- X# bar/one just has a simple pair
- Xoldfile 11 ns/bar/one/99 <<!
- XMessage-ID: <gya.bar/one/99>
- XShould-expire: yes
- XSubject: bar one/99
- X
- Xbody
- X!
- Xoldfile 10 ns/bar/one/100 <<!
- XMessage-ID: <hn.bar/one/100>
- XShould-expire: no
- XSubject: bar one/100
- X
- Xbody
- X!
- X
- X# bletch/one just has a simple pair
- Xoldfile 11 ns/bletch/one/99 <<!
- XMessage-ID: <iya.bletch/one/99>
- XShould-expire: yes
- XSubject: bletch one/99
- X
- Xbody
- X!
- Xoldfile 10 ns/bletch/one/100 <<!
- XMessage-ID: <jn.bletch/one/100>
- XShould-expire: no
- XSubject: bletch one/100
- X
- Xbody
- X!
- X
- X# foo.two has a simple pair again
- Xoldfile 14 ns/foo/two/99 <<!
- XMessage-ID: <kn.foo/two/99>
- XShould-expire: no
- XSubject: foo two/99
- X
- Xbody
- X!
- Xoldfile 16 ns/foo/two/100 <<!
- XMessage-ID: <lym.foo/two/100>
- XShould-expire: yes
- XSubject: foo two/100
- X
- Xbody
- X!
- X
- X# bar.two, another simple pair
- Xoldfile 14 ns/bar/two/99 <<!
- XMessage-ID: <mn.bar/two/99>
- XShould-expire: no
- XSubject: bar two/99
- X
- Xbody
- X!
- Xoldfile 16 ns/bar/two/100 <<!
- XMessage-ID: <nym.bar/two/100>
- XShould-expire: yes
- XSubject: bar two/100
- X
- Xbody
- X!
- X
- X# foo.three adds a purge date
- Xoldfile 4 ns/foo/three/98 <<!
- XMessage-ID: <on.foo/three/98>
- XShould-expire: no
- XSubject: foo three/98
- X
- Xbody
- X!
- Xoldfile 6 ns/foo/three/99 <<!
- XMessage-ID: <pyu.foo/three/99>
- XShould-expire: yes
- XSubject: foo three/99
- X
- Xbody
- X!
- Xoldfile 16 ns/foo/three/100 <<!
- XMessage-ID: <qyu.foo/three/100>
- XShould-expire: yes
- XExpires: `olddate -1`
- XSubject: foo three/100
- X
- Xbody
- X!
- X
- X# bletch.four has both a retain date and a purge date
- Xoldfile 9 ns/bletch/four/97 <<!
- XMessage-ID: <rn.bletch/four/97>
- XShould-expire: no
- XSubject: bletch four/97
- X
- Xbody
- X!
- Xoldfile 11 ns/bletch/four/98 <<!
- XMessage-ID: <sym.bletch/four/98>
- XShould-expire: yes
- XSubject: bletch four/98
- X
- Xbody
- X!
- Xoldfile 3 ns/bletch/four/99 <<!
- XMessage-ID: <tn.bletch/four/99>
- XShould-expire: no
- XExpires: `olddate 1`
- XSubject: bletch four/99
- X
- Xbody
- X!
- Xoldfile 25 ns/bletch/four/100 <<!
- XMessage-ID: <uym.bletch/four/100>
- XShould-expire: yes
- XExpires: `olddate -1`
- XSubject: bletch four/100
- X
- Xbody
- X!
- X
- X# bar.five gets the catchall at the end and is another simple pair.
- Xoldfile 31 ns/bar/five/99 <<!
- XMessage-ID: <vy-.bar/five/99>
- XShould-expire: yes
- XSubject: bar five/99
- X
- Xbody
- X!
- Xoldfile 29 ns/bar/five/100 <<!
- XMessage-ID: <wn.bar/five/100>
- XShould-expire: no
- XSubject: bar five/100
- X
- Xbody
- X!
- X
- X# bletch.six is not in the active file, but is otherwise orthodox
- Xoldfile 31 ns/bletch/six/99 <<!
- XMessage-ID: <xy-.bletch/six/99>
- XShould-expire: yes
- XSubject: bletch six/99
- X
- Xbody
- X!
- Xoldfile 29 ns/bletch/six/100 <<!
- XMessage-ID: <yn.bletch/six/100>
- XShould-expire: no
- XSubject: bletch six/100
- X
- Xbody
- X!
- END_OF_FILE
- if test 3614 -ne `wc -c <'expire/ns.p'`; then
- echo shar: \"'expire/ns.p'\" unpacked with wrong size!
- fi
- # end of 'expire/ns.p'
- fi
- if test -f 'expire/xargs.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'expire/xargs.c'\"
- else
- echo shar: Extracting \"'expire/xargs.c'\" \(3713 characters\)
- sed "s/^X//" >'expire/xargs.c' <<'END_OF_FILE'
- X/*
- X * xargs - gather up filenames from input and run command on them
- X */
- X
- X#include <stdio.h>
- X#include <sys/param.h>
- X
- X#define STREQ(a, b) (strcmp((a), (b)) == 0)
- X
- X#ifndef lint
- Xstatic char Sccsid[] = "@(#)xargs.c 1.2 of 6 May 86";
- X#endif
- X
- Xchar argchars[NCARGS]; /* Characters of arguments. */
- Xchar *argfree = argchars; /* First free char in argchars. */
- Xchar *argbase = argchars; /* First char after constant args. */
- X
- Xchar *argptrs[NCARGS/sizeof(char *)]; /* Pointers to arguments. */
- Xint nargs = 0; /* Number of entries in argptrs. */
- Xint base = 0; /* Number of constant entries. */
- X
- Xint size = 0; /* Size of total argument bundle so far. */
- Xint basesize = 0; /* Size of constant args. */
- X#ifndef XARGMAX
- X#define XARGMAX (NCARGS - 50) /* 50 is misc. overhead plus safety margin. */
- X#endif
- X
- X#ifndef OKSTAT
- X#define OKSTAT 1 /* Highest exit status considered normal. */
- X#endif
- X
- Xextern char **environ;
- X
- Xchar *progname;
- Xextern char *mkprogname();
- X
- X/*
- X * main - parse arguments, handle options, main control
- X */
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int c;
- X int errflg = 0;
- X char *cmd;
- X register char **envp;
- X char buf[BUFSIZ];
- X register int len;
- X int maxstat = 0;
- X int thisstat;
- X extern int optind;
- X extern char *optarg;
- X
- X progname = mkprogname(argv[0]);
- X
- X while ((c = getopt(argc, argv, "")) != EOF)
- X switch (c) {
- X case '?':
- X default:
- X errflg++;
- X break;
- X }
- X if (errflg || optind == argc) {
- X fprintf(stderr, "Usage: %s command [arg] ...\n", progname);
- X exit(2);
- X }
- X
- X /* Plug in the constant arguments. */
- X cmd = argv[optind];
- X for (; optind < argc; optind++) {
- X argptrs[nargs++] = argv[optind];
- X size += strlen(argv[optind]) + 1 + sizeof(char *);
- X }
- X
- X /* Add in the size of the environment. */
- X for (envp = environ; *envp != NULL; envp++)
- X size += strlen(*envp) + 1 + sizeof(char *);
- X
- X /* Establish base. */
- X argbase = argfree;
- X base = nargs;
- X basesize = size;
- X if (basesize >= XARGMAX) {
- X fprintf(stderr, "%s: command too big\n", progname);
- X exit(2);
- X }
- X
- X /* And do it. */
- X while (fgets(buf, (int)sizeof(buf), stdin) != NULL) {
- X len = strlen(buf);
- X if (buf[len-1] == '\n')
- X buf[len-1] = '\0';
- X if (basesize + len + 1 + sizeof(char *) >= XARGMAX) {
- X fprintf(stderr, "%s: filename too long: ", progname);
- X fputs(buf, stdout);
- X putchar('\n');
- X } else {
- X if (size + len + 1 + sizeof(char *) >= XARGMAX) {
- X argptrs[nargs++] = NULL;
- X thisstat = runone(cmd, argptrs);
- X if (thisstat > maxstat)
- X maxstat = thisstat;
- X argfree = argbase;
- X nargs = base;
- X size = basesize;
- X }
- X (void) strcpy(argfree, buf);
- X argptrs[nargs++] = argfree;
- X argfree += len + 1;
- X size += len + 1 + sizeof(char *);
- X }
- X }
- X if (nargs > base) { /* If there are any loose ends... */
- X argptrs[nargs++] = NULL;
- X thisstat = runone(cmd, argptrs);
- X if (thisstat > maxstat)
- X maxstat = thisstat;
- X }
- X
- X exit(maxstat);
- X}
- X
- X/*
- X * runone - run the command
- X */
- Xint /* status of command */
- Xrunone(cmd, ptrs)
- Xchar *cmd;
- Xchar **ptrs;
- X{
- X register int pid;
- X int status;
- X int stexit, stcause;
- X register int wpid;
- X
- X#ifdef DEBUG
- X fprintf(stderr, "run %s ... %s %s ...\n", cmd, ptrs[0], ptrs[1]);
- X#endif
- X while ((pid = fork()) < 0)
- X sleep(10);
- X if (pid == 0) { /* Daughter. */
- X close(0);
- X if (open("/dev/null", 0) != 0) {
- X fprintf(stderr, "%s: can't open /dev/null\n", progname);
- X exit(2);
- X }
- X execvp(cmd, ptrs);
- X fprintf(stderr, "%s: can't find `%s'\n", progname, cmd);
- X exit(2);
- X } else { /* Parent. */
- X do {
- X wpid = wait(&status);
- X } while (wpid >= 0 && wpid != pid);
- X stexit = (status>>8)&0377;
- X stcause = status&0377;
- X if (stcause != 0 || stexit > OKSTAT) {
- X fprintf(stderr, "%s: `%s' failed\n", progname, cmd);
- X exit(2);
- X }
- X return(stexit);
- X }
- X /* NOTREACHED */
- X}
- END_OF_FILE
- if test 3713 -ne `wc -c <'expire/xargs.c'`; then
- echo shar: \"'expire/xargs.c'\" unpacked with wrong size!
- fi
- # end of 'expire/xargs.c'
- fi
- if test -f 'libcnews/path.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libcnews/path.c'\"
- else
- echo shar: Extracting \"'libcnews/path.c'\" \(3615 characters\)
- sed "s/^X//" >'libcnews/path.c' <<'END_OF_FILE'
- X/*
- X * news path names (and umask)
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include "news.h"
- X#include "newspaths.h"
- X
- X#ifndef NULL
- X#define NULL 0
- X#endif
- X
- X#ifndef NEWSCTL
- X#define NEWSCTL "/usr/lib/news"
- X#endif
- X#ifndef NEWSARTS
- X#define NEWSARTS "/usr/spool/news"
- X#endif
- X#ifndef NEWSBIN
- X#define NEWSBIN "/usr/lib/newsbin"
- X#endif
- X#ifndef NEWSUMASK
- X#define NEWSUMASK 002
- X#endif
- X
- Xstatic char *pwd = NULL; /* Current directory, NULL means unknown. */
- Xstatic int dirsset = NO; /* Have the following been set? */
- Xstatic char *arts;
- Xstatic char *bin;
- Xstatic char *ctl;
- X#define DIRS() if (!dirsset) setdirs()
- Xvoid setdirs();
- X
- Xextern char *strcpy();
- Xextern char *strcat();
- Xextern char *getenv();
- X
- Xextern void unprivileged(); /* user-supplied privilege dropper */
- X
- X/*
- X - spoolfile - historical synonym for artfile
- X */
- Xchar *
- Xspoolfile(base)
- Xchar *base;
- X{
- X static char wholefile[MAXFILE];
- X
- X DIRS();
- X
- X if (base == NULL) { /* he just wants the directory */
- X (void) strcpy(wholefile, arts);
- X return wholefile;
- X }
- X
- X if (pwd != NULL && STREQ(pwd, arts))
- X (void) strcpy(wholefile, "");
- X else {
- X (void) strcpy(wholefile, arts);
- X (void) strcat(wholefile, SFNDELIM);
- X }
- X (void) strcat(wholefile, base);
- X
- X return wholefile;
- X}
- X
- X/*
- X - artfile - best pathname for a file in NEWSARTS
- X */
- Xchar *
- Xartfile(base)
- Xchar *base;
- X{
- X return spoolfile(base);
- X}
- X
- X/*
- X - fullartfile - full pathname for a file in NEWSARTS
- X */
- Xchar *
- Xfullartfile(base)
- Xchar *base;
- X{
- X register char *p;
- X register char *pwdsave;
- X
- X pwdsave = pwd;
- X pwd = NULL; /* fool spoolfile() into giving full path */
- X p = spoolfile(base);
- X pwd = pwdsave;
- X return p;
- X}
- X
- X/*
- X - fullspoolfile - historical synonym for fullartfile
- X */
- Xchar *
- Xfullspoolfile(base)
- Xchar *base;
- X{
- X return fullartfile(base);
- X}
- X
- X/*
- X - libfile - historical synonym for ctlfile
- X */
- Xchar *
- Xlibfile(base)
- Xchar *base;
- X{
- X static char wholefile[MAXFILE];
- X
- X DIRS();
- X
- X (void) strcpy(wholefile, ctl);
- X if (base != NULL) {
- X (void) strcat(wholefile, SFNDELIM);
- X (void) strcat(wholefile, base);
- X }
- X return wholefile;
- X}
- X
- X/*
- X - ctlfile - full pathname for a file in NEWSCTL
- X */
- Xchar *
- Xctlfile(base)
- Xchar *base;
- X{
- X return libfile(base);
- X}
- X
- X/*
- X - binfile - full pathname for a file in NEWSBIN
- X */
- Xchar *
- Xbinfile(base)
- Xchar *base;
- X{
- X static char wholefile[MAXFILE];
- X
- X DIRS();
- X
- X (void) strcpy(wholefile, bin);
- X if (base != NULL) {
- X (void) strcat(wholefile, SFNDELIM);
- X (void) strcat(wholefile, base);
- X }
- X return wholefile;
- X}
- X
- X/*
- X - cd - change to a directory, with checking
- X */
- Xvoid
- Xcd(dir)
- Xchar *dir;
- X{
- X if (chdir(dir) < 0)
- X errunlock("cannot chdir(%s)", dir);
- X pwd = dir;
- X}
- X
- X/*
- X - setdirs - set up directories from environment, for use by other functions
- X *
- X * Invokes user-supplied function unprivileged() if non-standard values used.
- X */
- Xstatic void
- Xsetdirs()
- X{
- X register char *p;
- X register int nonstd = NO;
- X
- X if (dirsset)
- X return;
- X
- X p = getenv("NEWSARTS");
- X if (p == NULL)
- X arts = NEWSARTS;
- X else {
- X arts = p;
- X nonstd = YES;
- X }
- X
- X p = getenv("NEWSCTL");
- X if (p == NULL)
- X ctl = NEWSCTL;
- X else {
- X ctl = p;
- X nonstd = YES;
- X }
- X
- X p = getenv("NEWSBIN");
- X if (p == NULL)
- X bin = NEWSBIN;
- X else {
- X bin = p;
- X nonstd = YES;
- X }
- X
- X dirsset = YES;
- X if (nonstd)
- X unprivileged();
- X}
- X
- X/*
- X - newsumask - return suitable value of umask for news stuff
- X */
- Xint
- Xnewsumask()
- X{
- X register char *p;
- X register char *scan;
- X register int mask;
- X
- X p = getenv("NEWSUMASK");
- X if (p == NULL)
- X return(NEWSUMASK);
- X else {
- X mask = 0;
- X for (scan = p; *scan != '\0'; scan++)
- X if ('0' <= *scan && *scan <= '7' && mask <= 077)
- X mask = (mask << 3) | (*scan - '0');
- X else /* Garbage, ignore it. */
- X return(NEWSUMASK);
- X return(mask);
- X }
- X}
- END_OF_FILE
- if test 3615 -ne `wc -c <'libcnews/path.c'`; then
- echo shar: \"'libcnews/path.c'\" unpacked with wrong size!
- fi
- # end of 'libcnews/path.c'
- fi
- if test -f 'mail/coder/uudecode.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mail/coder/uudecode.c'\"
- else
- echo shar: Extracting \"'mail/coder/uudecode.c'\" \(3280 characters\)
- sed "s/^X//" >'mail/coder/uudecode.c' <<'END_OF_FILE'
- X
- X/* based on 5.1 (Berkeley) 7/2/83 */
- X
- X/*
- X * uudecode [input]
- X *
- X * create the specified file, decoding as you go.
- X * used with uuencode.
- X */
- X#include <stdio.h>
- X#include <pwd.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- Xmain(argc, argv)
- Xchar **argv;
- X{
- X FILE *in, *out;
- X int mode = 0777;
- X char dest[128];
- X char buf[80];
- X char *strcpy(), *strcat();
- X
- X /* optional input arg */
- X if (argc > 1) {
- X if ((in = fopen(argv[1], "r")) == NULL) {
- X perror(argv[1]);
- X exit(1);
- X }
- X argv++; argc--;
- X } else
- X in = stdin;
- X
- X if (argc != 1) {
- X (void) fprintf(stderr, "Usage: uudecode [infile]\n");
- X exit(2);
- X }
- X
- X /* search for header line */
- X for (;;) {
- X if (fgets(buf, sizeof buf, in) == NULL) {
- X (void) fprintf(stderr, "No begin line\n");
- X exit(3);
- X }
- X if (strncmp(buf, "begin ", 6) == 0)
- X break;
- X }
- X dest[0] = '\0';
- X (void) sscanf(buf, "begin %o %s", &mode, dest);
- X
- X /* handle ~user/file format */
- X if (dest[0] == '~') {
- X char *sl;
- X struct passwd *getpwnam();
- X char *index();
- X struct passwd *user;
- X char dnbuf[100];
- X
- X sl = index(dest, '/');
- X if (sl == NULL) {
- X (void) fprintf(stderr, "Illegal ~user\n");
- X exit(3);
- X }
- X *sl++ = 0;
- X user = getpwnam(dest+1);
- X if (user == NULL) {
- X (void) fprintf(stderr, "No such user as %s\n", dest);
- X exit(4);
- X }
- X (void) strcpy(dnbuf, user->pw_dir);
- X (void) strcat(dnbuf, "/");
- X (void) strcat(dnbuf, sl);
- X (void) strcpy(dest, dnbuf);
- X }
- X
- X /* create output file */
- X out = fopen(dest, "w");
- X if (out == NULL) {
- X perror(dest);
- X exit(4);
- X }
- X (void) chmod(dest, mode);
- X
- X decode(in, out);
- X
- X if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) {
- X (void) fprintf(stderr, "No end line\n");
- X exit(5);
- X }
- X exit(0);
- X}
- X
- X/*
- X * copy from in to out, decoding as you go along.
- X */
- Xdecode(in, out)
- XFILE *in;
- XFILE *out;
- X{
- X register char *ibp, *obp;
- X register int inbyte, outbyte;
- X register int loops, incount;
- X char inbuf[120]; /* allow for uuencode to grow lines */
- X char outbuf[120];
- X
- X/* single character decode */
- X#define DEC(c) (((c) - ' ') & 077) /* N.B.: c is evaluated exactly once */
- X
- X for (; ; ) {
- X if (fgets(inbuf, sizeof inbuf, in) == NULL) {
- X (void) printf("Short file\n");
- X exit(10); /* premature EOF */
- X }
- X incount = DEC(inbuf[0]);
- X if (incount <= 0)
- X break; /* EOF */
- X
- X ibp = &inbuf[1]; /* skip line length */
- X obp = outbuf;
- X for (loops = incount / 3; --loops >= 0; ) { /* inner loop */
- X /*
- X * output a group of 3 bytes (4 input characters).
- X * the input chars are pointed to by ibp, they are to
- X * be output via obp. incount is used to tell us
- X * not to output all of them at the end of the line.
- X */
- X outbyte = DEC(*ibp++) << 2;
- X *obp++ = outbyte | ((inbyte = DEC(*ibp++)) >> 4);
- X outbyte = inbyte << 4;
- X *obp++ = outbyte | ((inbyte = DEC(*ibp++)) >> 2);
- X *obp++ = (inbyte << 6) | DEC(*ibp++);
- X }
- X loops = incount % 3;
- X if (loops > 0) {
- X /*
- X * finish off the remaining bytes (loops < 3).
- X */
- X if (--loops >= 0) {
- X outbyte = DEC(*ibp++) << 2;
- X *obp++ = outbyte | ((inbyte = DEC(*ibp++)) >> 4);
- X }
- X if (--loops >= 0) {
- X outbyte = inbyte << 4;
- X *obp++ = outbyte | ((inbyte = DEC(*ibp++)) >> 2);
- X }
- X if (--loops >= 0)
- X *obp++ = (inbyte << 6) | DEC(*ibp++);
- X }
- X *obp = '\0';
- X (void) fwrite(outbuf, 1, obp - outbuf, out);
- X }
- X}
- END_OF_FILE
- if test 3280 -ne `wc -c <'mail/coder/uudecode.c'`; then
- echo shar: \"'mail/coder/uudecode.c'\" unpacked with wrong size!
- fi
- # end of 'mail/coder/uudecode.c'
- fi
- if test -f 'rna/active.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rna/active.c'\"
- else
- echo shar: Extracting \"'rna/active.c'\" \(3032 characters\)
- sed "s/^X//" >'rna/active.c' <<'END_OF_FILE'
- X/*
- X * active file handling routines
- X *
- X * format of file:
- X * <groupname> ' ' <5 digit #> ' ' <5 digit #> ' ' flag '\n'
- X * (seq) (low)
- X */
- X
- X#include "defs.h"
- X
- Xstatic char actname[] = ACTIVE;
- Xstatic int lineno;
- Xstatic active *alist;
- X
- X/*
- X * getseq - Get next sequence number for this group
- X * and update active file.
- X * If group missing append to file.
- X */
- Xchar *
- Xgetseq(group)
- Xchar *group;
- X{
- X register FILE *f;
- X register int i;
- X char gbuf[BUFSIZ / 2], dbuf[BUFSIZ / 4], dbuf2[BUFSIZ / 4];
- X extern char *itoa();
- X
- X f = fopenl(actname);
- X lineno = 0;
- X while (getline(f, gbuf, dbuf, dbuf2))
- X if (CMP(gbuf, group) == 0) {
- X i = atoi(dbuf);
- X i++;
- X fseek(f, -12L, 1);
- X (void) fprintf(f, "%05d", i);
- X fclose(f);
- X#if !AUSAM
- X unlock(actname);
- X#endif
- X return itoa(i);
- X }
- X (void) fprintf(f, "%s 00001 00001 y\n", group);
- X fclose(f);
- X#if !AUSAM
- X unlock(actname);
- X#endif
- X return itoa(1);
- X}
- X
- X
- Xstatic
- Xgetline(f, g, d, d2)
- Xregister FILE *f;
- Xchar *g, *d, *d2;
- X{
- X register int c;
- X register char *s;
- X
- X lineno++;
- X s = g;
- X while ((c = getc(f)) != ' ' && c != EOF)
- X *s++ = c;
- X *s = '\0';
- X
- X if (c != EOF) {
- X s = d;
- X while ((c = getc(f)) != EOF && isdigit(c))
- X *s++ = c;
- X *s = '\0';
- X
- X s = d2;
- X if (c == ' ')
- X while ((c = getc(f)) != EOF && isdigit(c))
- X *s++ = c;
- X *s = '\0';
- X
- X if (c == ' ')
- X while ((c = getc(f)) != EOF && c != '\n')
- X ; /* eat flag */
- X }
- X
- X if (c != EOF && (c != '\n' || !*d || !*d2))
- X error("%s: bad format: line %d", actname, lineno);
- X return c != EOF;
- X}
- X
- X
- X/*
- X * build internal active file structure
- X */
- Xactive *
- Xreadactive()
- X{
- X register FILE *f;
- X register active *ap, *last;
- X char gbuf[BUFSIZ / 2], dbuf[BUFSIZ / 4], dbuf2[BUFSIZ / 4];
- X
- X alist = last = NIL(active);
- X f = fopenf(actname, "r");
- X lineno = 0;
- X while (getline(f, gbuf, dbuf, dbuf2)) {
- X ap = NEW(active);
- X ap->a_name = newstr(gbuf);
- X ap->a_seq = atoi(dbuf);
- X ap->a_low = atoi(dbuf2);
- X ap->a_next = NIL(active);
- X if (!alist)
- X alist = ap;
- X else
- X last->a_next = ap;
- X last = ap;
- X }
- X fclose(f);
- X return alist;
- X}
- X
- X
- X/*
- X * return pointer to named group
- X */
- Xactive *
- Xactivep(grp)
- Xregister char *grp;
- X{
- X register active *ap;
- X
- X for (ap = alist; ap; ap = ap->a_next)
- X if (CMP(grp, ap->a_name) == 0)
- X break;
- X return ap;
- X}
- X
- X
- X/*
- X * setlow - set the low number for this group
- X */
- Xsetlow(group, low)
- Xchar *group;
- Xint low;
- X{
- X register FILE *f;
- X char gbuf[BUFSIZ / 2], dbuf[BUFSIZ / 4], dbuf2[BUFSIZ / 4];
- X extern char *itoa();
- X
- X f = fopenl(actname);
- X lineno = 0;
- X while (getline(f, gbuf, dbuf, dbuf2))
- X if (CMP(gbuf, group) == 0) {
- X fseek(f, -6L, 1);
- X (void) fprintf(f, "%05d", low);
- X break;
- X }
- X fclose(f);
- X#if !AUSAM
- X unlock(actname);
- X#endif
- X}
- X
- X
- X
- X/*
- X * initgrp - initialise an entry for this group
- X */
- Xinitgrp(group)
- Xchar *group;
- X{
- X register FILE *f;
- X char gbuf[BUFSIZ / 2], dbuf[BUFSIZ / 4], dbuf2[BUFSIZ / 4];
- X
- X f = fopenl(actname);
- X lineno = 0;
- X while (getline(f, gbuf, dbuf, dbuf2))
- X if (CMP(gbuf, group) == 0) {
- X#if !AUSAM
- X unlock(actname);
- X#endif
- X return;
- X }
- X (void) fprintf(f, "%s 00000 00001\n", group);
- X
- X}
- END_OF_FILE
- if test 3032 -ne `wc -c <'rna/active.c'`; then
- echo shar: \"'rna/active.c'\" unpacked with wrong size!
- fi
- # end of 'rna/active.c'
- fi
- if test -f 'rna/history.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rna/history.c'\"
- else
- echo shar: Extracting \"'rna/history.c'\" \(3647 characters\)
- sed "s/^X//" >'rna/history.c' <<'END_OF_FILE'
- X/*
- X * History file
- X * each line contains a message-id, install or expire time
- X * names of linked files
- X */
- X
- X#include "defs.h"
- X
- Xstatic char histname[] = HISTORY;
- Xstatic char *histid; /* messageid to save */
- Xstatic char *histline; /* list of linked files */
- Xstatic long etime; /* expire time */
- X
- Xtypedef enum stypes {
- X chk, delete } stype;
- X
- X/*
- X * do things with history file
- X * chk - see if id present
- X * delete - delete article with id
- X */
- Xstatic bool
- Xsearchhist(id, type)
- Xchar *id;
- Xstype type;
- X{
- X register FILE *f;
- X register char *s, *name;
- X register bool found;
- X char buf[BUFSIZ * 2];
- X
- X extern char *newsdir;
- X
- X f = fopenl(histname);
- X
- X found = false;
- X while (fgets(buf, sizeof(buf), f)) {
- X if (s = strchr(buf, ' '))
- X *s = '\0';
- X else
- X error("Bad format: %s", histname);
- X if (CMP(buf, id) == 0) {
- X found = true;
- X break;
- X }
- X }
- X if (found && type == delete) {
- X if ((name = strchr(s + 1, ' ')) == NIL(char))
- X error("Bad format: %s", histname);
- X name++;
- X while (name && (s = strpbrk(name, " \n"))) {
- X *s = '\0';
- X name = newstr3(newsdir, "/", name);
- X remove(name);
- X free(name);
- X name = s + 1;
- X }
- X }
- X fclose(f);
- X#if !AUSAM
- X unlock(histname);
- X#endif
- X return found;
- X}
- X
- X
- X/*
- X * delete files given id
- X */
- Xbool
- Xcancel(id)
- Xchar *id;
- X{
- X bool searchhist();
- X
- X return searchhist(id, delete);
- X}
- X
- X
- X/*
- X * check if article has been recieved
- X */
- Xbool
- Xchkhist(id)
- Xchar *id;
- X{
- X bool searchhist();
- X
- X return searchhist(id, chk);
- X}
- X
- X
- X/*
- X * scan history, clearing uflag list entry if id not seen
- X */
- Xscanhist(ulist, usize)
- Xchar **ulist;
- Xint usize;
- X{
- X register FILE *f;
- X register char *s, **found;
- X register int i;
- X char *key[1];
- X char buf[BUFSIZ * 2];
- X bool * seen;
- X
- X extern char *newsdir;
- X
- X seen = (bool * ) myalloc((int) sizeof(bool) * usize);
- X memset((char *)seen, 0, (int) sizeof(bool) * usize);
- X
- X f = fopenf(histname, "r");
- X while (fgets(buf, sizeof(buf), f)) {
- X if (s = strchr(buf, ' '))
- X *s = '\0';
- X else
- X error("Bad format: %s", histname);
- X key[0] = buf;
- X found = (char **) bsearch((char *) key, (char *) ulist, (unsigned) usize,
- X sizeof(char *), strpcmp);
- X if (found)
- X seen[found - ulist] = true;
- X }
- X fclose(f);
- X
- X for (i = 0; i < usize; i++)
- X if (!seen[i]) {
- X free(ulist[i]);
- X ulist[i] = NIL(char);
- X }
- X free((char *)seen);
- X}
- X
- X
- X/*
- X * open hist file, write id and time
- X */
- Xopenhist(hp)
- Xheader *hp;
- X{
- X
- X histid = newstr(hp->h_messageid);
- X if (hp->h_expires)
- X etime = atot(hp->h_expires);
- X else
- X etime = 0L;
- X histline = NIL(char);
- X}
- X
- X
- X/*
- X * write name of file article resides into history file
- X */
- Xwritehist(fname)
- Xchar *fname;
- X{
- X histline = (histline ? catstr2(histline, " ", fname) : newstr(fname));
- X}
- X
- X
- X/*
- X * close history file
- X */
- Xclosehist()
- X{
- X register FILE *f;
- X extern long now;
- X
- X f = fopenl(histname);
- X fseek(f, 0L, 2);
- X (void) fprintf(f, "%s %s%ld %s\n", histid, etime ? "E" : "", etime ? etime :
- X now, histline);
- X fclose(f);
- X#if !AUSAM
- X unlock(histname);
- X#endif
- X free(histid);
- X free(histline);
- X}
- X
- X
- X/*
- X * remove a news item
- X * check owner first
- X */
- Xstatic
- Xremove(fname)
- Xchar *fname;
- X{
- X header h;
- X FILE * f;
- X register char *s, *mname;
- X
- X#if AUSAM
- X extern struct pwent pe;
- X#else
- X extern struct passwd *pp;
- X#endif
- X extern char systemid[];
- X extern bool su;
- X extern bool pflag;
- X
- X if (!su && !pflag) {
- X f = fopenf(fname, "r");
- X gethead(f, &h);
- X fclose(f);
- X if (s = strchr(h.h_from, ' '))
- X *s = '\0';
- X mname = newstr5(
- X#if AUSAM
- X pe.pw_strings[LNAME],
- X#else
- X pp->pw_name,
- X#endif
- X "@", systemid, ".", MYDOMAIN);
- X if (CMP(mname, h.h_from) != 0)
- X error("Can't cancel articles you didn't write.");
- X free(mname);
- X }
- X if (unlink(fname) != 0)
- X error("Couldn't unlink %s", fname);
- X
- X}
- END_OF_FILE
- if test 3647 -ne `wc -c <'rna/history.c'`; then
- echo shar: \"'rna/history.c'\" unpacked with wrong size!
- fi
- # end of 'rna/history.c'
- fi
- if test -f 'rnews/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rnews/README'\"
- else
- echo shar: Extracting \"'rnews/README'\" \(3793 characters\)
- sed "s/^X//" >'rnews/README' <<'END_OF_FILE'
- XThis is an alpha test release. Do not distribute modified copies of it;
- Xsee the COPYRIGHT file for details.
- X
- XSend bug reports to utzoo!cnews-alpha. This software is believed to
- Xwork, though it could doubtless stand some improvement. The code is
- Xgoing to be cleaned up and possibly sped up before general release.
- X
- X
- X``yer about to be boarded, ye scurvy network news dogs! har har ...''
- X -- Oliver Wendell Jones, Bloom County Hacker & Cracker
- X
- X``No news is good news.''
- X``When bigger machines are built, netnews will saturate them.''
- X``USENET -- All the news that's fit to `N'.''
- X -- /usr/games/fortune
- X
- X``B news is Bad news.''
- X``Net news is the television of computing.''
- X -- Geoff Collyer
- X
- XDoes your inews wallow in the mud like a pregnant sow? Does your expire
- Xflop on its back, wiggle its feet and gurgle pathetically? Then you
- Xneed new, improved *C news*, the sentient being's news system: no more
- Xodious Relay-Version headers, no more sluggish machines caused by
- Xoverfed news software. Real locking. No line-eater bugs.
- X
- XAvailable from fine news administrators everywhere. C news.
- X___
- X
- XAssumptions:
- X you already have B news and possibly rn running
- X you personally installed B news
- X you are now upgrading to C news
- X
- XBefore using make for anything else, you must
- X
- X make variant
- X
- Xwhere variant is your UNIX variant: v7, v8, v9, bsd42 or usg.
- XIt will tell you to edit the makefile DEPSRC and DEPOBJ definitions to match.
- X
- XIf you need a roadmap, see ../usr.lib/README.
- X
- X../expire and ../time require that /usr/include/time.h exists.
- XIf it doesn't exist on your (4.2BSD) system, thanks to gratuitous
- Xtinkering (at UCB), execute
- X
- X cd /usr/include; ln -s sys/time.h
- X
- XThis may require super-user privileges, which should be easy to obtain
- Xon 4.2.
- X
- XAfter compiling inews, install it as /usr/lib/news/realinews,
- Xsetuid-news. On older systems, you will to also install a small
- Xprogram, setnewids, setuid-root. If this worries you, read
- Xsetnewsids.c; all it does is execute setgid(), setuid() to the "news"
- Xgroup and user if they exist, otherwise realinews's real ids. Install
- Xsh/inews as /usr/bin/inews, rnews.sh as /usr/bin/rnews and
- X/usr/bin/cunbatch. You can test realinews by giving NEWSCTL, NEWSBIN
- Xor NEWSARTS environment variables to change the library, binary or
- Xspool directories and I encourage this.
- X
- XIf you plan to run rn, you'll need the latest rn patches to allow Xref:
- Xto work without Relay-Version:.
- X
- XYou can get postnews from B news & Pnews from rn.
- X
- XYour sys file should not refer to a given batch file (with the F or f
- Xflags) more than once, or the batch file will be scrambled; this will be
- Xfixed and isn't a disaster as the C batcher is quite flexible and can
- Xcompensate. The Ln flag isn't yet fully implemented.
- X
- XIf your `domain' isn't "uucp", you will need to put your domain name in
- X/usr/lib/news/domain. No upper case letters in your new domain please,
- Xthere is no call for it and it just looks ugly.
- X
- XYou must remove /usr/lib/news/LOCK* and /usr/lib/news/lock.* somewhere
- Xin /etc/rc*. Thus you must only permit rnews to run on file servers.
- X
- XYou'll need compress for compressing or uncompressing batches of news.
- XSee the contact person of your news feed or the moderator of the
- Xnewsgroup comp.sources.unix.
- X
- XSee the anews directory for conversion filters from A to B and back.
- X
- XYou'll need to install /usr/lib/news/gngp (see ../gngp) before inews
- Xwill work.
- X
- XB-2.11-isms: your /usr/lib/news/mailpaths file must be updated to point
- Xat your nearest backbone site. A 5th sys file field for Distribution:
- Xpatterns is here (add them in sys after the subscription list, separated
- Xby "/"), and a 6th field for excluded hosts is half-here, separated by
- X"/" from the system name. Active file support for 4 fields and the m
- Xflag are here.
- X
- XGood Luck.
- X
- X Geoff Collyer
- END_OF_FILE
- if test 3793 -ne `wc -c <'rnews/README'`; then
- echo shar: \"'rnews/README'\" unpacked with wrong size!
- fi
- # end of 'rnews/README'
- fi
- if test -f 'rnews/active.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rnews/active.c'\"
- else
- echo shar: Extracting \"'rnews/active.c'\" \(3462 characters\)
- sed "s/^X//" >'rnews/active.c' <<'END_OF_FILE'
- X/*
- X * active file access functions (in-memory version)
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "active.h"
- X#include "news.h"
- X#include "newspaths.h"
- X
- X#define MAXNGS 2000
- X
- Xstatic FILE *fp = NULL;
- Xstatic char filerelname[] = "active";
- Xstatic char *active = NULL; /* points at entire active file */
- Xstatic int actsize; /* bytes in active: type int determined by fread */
- Xstatic unsigned artlines; /* lines in artlnps actually used */
- X/* TODO: make this a linked list or realloc to avoid the MAXNGS limit */
- Xstatic char *artlnps[MAXNGS]; /* point at lines in active file */
- X
- Xlong
- Xincartnum(ng, inc)
- Xchar *ng;
- Xint inc;
- X{
- X register int nglen = strlen(ng);
- X register char *pos;
- X register unsigned line = 0;
- X register long nextart = -1;
- X char artnumstr[ARTNUMWIDTH + 1];
- X extern char ldzeropad[];
- X
- X if (artload() != ST_OKAY)
- X return nextart;
- X while (pos = artlnps[line], line++ < artlines && pos[0] != '\0')
- X if (STREQN(pos, ng, nglen) && pos[nglen] == ' ') {
- X nextart = atol(&pos[nglen + 1]) + inc;
- X (void) sprintf(artnumstr, ldzeropad,
- X ARTNUMWIDTH, ARTNUMWIDTH, nextart);
- X (void) strncpy(&pos[nglen + 1], artnumstr, ARTNUMWIDTH);
- X break;
- X }
- X return nextart;
- X}
- X
- Xint
- Xartload() /* reload any cached data */
- X{
- X int status = 0;
- X
- X if (fp == NULL)
- X if ((fp = fopenwclex(libfile(filerelname), "r+")) == NULL)
- X status |= ST_DROPPED;
- X if (fp != NULL && active == NULL) { /* file open, no cache */
- X struct stat sb;
- X
- X if (fstat(fileno(fp), &sb) < 0)
- X warning("can't fstat %s", libfile(filerelname));
- X else if (actsize = sb.st_size, /* squeeze into an int */
- X (unsigned)actsize != sb.st_size)
- X warning("%s won't fit into memory", libfile(filerelname));
- X else if ((active = malloc((unsigned)actsize+1)) == NULL)
- X warning("can't allocate memory for %s", libfile(filerelname));
- X else {
- X rewind(fp);
- X /* TODO: read with fgets to avoid linescan() */
- X if (fread(active, 1, actsize, fp) != actsize) {
- X warning("error reading %s", libfile(filerelname));
- X free(active);
- X active = NULL;
- X } else {
- X active[actsize] = '\0'; /* make a proper string */
- X if ((artlines = linescan(active, artlnps,
- X MAXNGS)) >= MAXNGS) {
- X extern char *progname;
- X
- X (void) fprintf(stderr,
- X "%s: too many newsgroups in %s\n",
- X progname, libfile(filerelname));
- X free(active);
- X active = NULL;
- X }
- X }
- X }
- X if (active == NULL)
- X status |= ST_DROPPED; /* give up! */
- X }
- X return status;
- X}
- X
- Xint
- Xartsync() /* sync to disk any cached data */
- X{
- X int status = 0;
- X
- X if (fp != NULL) {
- X rewind(fp);
- X if (active != NULL && fwrite(active, actsize, 1, fp) != 1 ||
- X fclose(fp) == EOF) {
- X warning("error writing %s", libfile(filerelname));
- X status |= ST_DROPPED;
- X }
- X }
- X fp = NULL;
- X if (active != NULL)
- X free(active); /* give back memory active used */
- X active = NULL;
- X return status;
- X}
- X
- X/*
- X * Store in lnarray the addresses of the starts of lines in s.
- X * Return the number of lines found; if greater than nent,
- X * store only nent and return nent.
- X */
- Xint
- Xlinescan(s, lnarray, nent)
- Xregister char *s;
- Xregister char **lnarray;
- Xregister int nent;
- X{
- X register int i = 0;
- X register char *nlp = s;
- X
- X if (i < nent)
- X lnarray[i++] = s;
- X while (i < nent && (nlp = index(nlp, '\n')) != NULL)
- X lnarray[i++] = ++nlp;
- X return i;
- X}
- X
- X/* ARGSUSED hdrs */
- Xmoderated(hdrs)
- Xstruct headers *hdrs;
- X{
- X /* TODO: look at 4th field of active file; needs new active.c hook */
- X return NO; /* stub */
- X}
- END_OF_FILE
- if test 3462 -ne `wc -c <'rnews/active.c'`; then
- echo shar: \"'rnews/active.c'\" unpacked with wrong size!
- fi
- # end of 'rnews/active.c'
- fi
- if test -f 'rnews/makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rnews/makefile'\"
- else
- echo shar: Extracting \"'rnews/makefile'\" \(3080 characters\)
- sed "s/^X//" >'rnews/makefile' <<'END_OF_FILE'
- X# makefile for C news relaynews
- X
- X# define NOSTOREVAL if your dbm store() returns no value (as in orig. v7)
- X# -I. for fcntl.h if present
- XDEFINES= -I../include -I. -DSTATIC=
- X# -Dvoid=int # if your compiler doesn't understand void's
- X# -DMAXLONG=017777777777L # if your compiler lacks "unsigned long" type
- X# -Dindex=strchr -Drindex=strrchr # if not on (System III or V or PWB)
- X
- XCFLAGS=-O -f68881 $(DEFINES) # -pg # -Z: John Bruner's Z0MAGIC (unmapped first page)
- XLIBS= -ldbm # -lstdio
- XLLIBS=-llocal
- XPROPTS=-l132
- XP=impr -p
- X
- XPOSSDEPFILES=fcntl.h gethostname.c getwd.c dbm.c mkdir.c ftime.c clsexec.c memcpy.c
- X# adjust next three lines for your OS; sources are links to vers/*/*.c
- XDEPHDR=
- XDEPSRC= clsexec.c memcpy.c zeropad.c
- XDEPOBJ= clsexec.o memcpy.o zeropad.o
- X
- XLIBSRCS= ../libcnews/*.c
- XLIBOBJS= ../libcnews/libcnews.a ../libc/libc.a
- XSRC=relaynews.c active.c caches.c checkdir.c control.c fileart.c \
- X headers.c history.c hostname.c io.c msgs.c procart.c \
- X string.c sys.c transmit.c $(DEPSRC) $(LIBSRCS)
- XOBJ=relaynews.o active.o caches.o checkdir.o control.o fileart.o \
- X headers.o history.o hostname.o io.o msgs.o procart.o \
- X string.o sys.o transmit.o $(DEPOBJ) $(LIBOBJS)
- XFILES=$(NONCFILES) $(CFILES)
- XNONCFILES= TODO* COPYRIGHT README ads/README ads/[0-9]* \
- X inews anne.jones tear rnews makefile
- XCFILES= ../include/*.h cpu.h headers.h system.h $(DEPHDR) $(SRC)
- XLINT=lint
- XLINTFLAGS=-haz $(DEFINES)
- X
- Xrelaynews: $(OBJ) ../libcnews/*.c
- X (cd ../libcnews; make)
- X $(CC) $(CFLAGS) $(OBJ) $(LIBS) -o $@
- Xlint: $(SRC)
- X $(LINT) $(LINTFLAGS) $(SRC) $(LIBS) $(LLIBS) | egrep -v ':$$'
- Xlintport: $(SRC)
- X $(LINT) $(LINTFLAGS) -p $(SRC) $(LIBS) $(LLIBS)
- X
- XTODO.grep: TODO
- X -egrep TODO TODO ../include/*.h *.h *.c sh/* >$@
- X -egrep TODO ../libc/memcpy.fast/src/*.c ../libcnews/*.c >>$@
- X
- Xv7 v8 v9 usg bsd42: clean
- X for file in vers/$@/*.c; do ln $$file; done
- X @echo 'Now edit makefile DEPSRC and DEPOBJ definitions to match:'
- X @echo vers/$@/*.c | sed 's;vers/$@/;;g'
- X
- Xprint: printc printnonc
- X touch $@
- Xprintc: $(CFILES)
- X /usr/bin/pp -T300 -fR $? | dimp -t | impr
- X touch $@
- Xprintnonc: $(NONCFILES)
- X pr $(PROPTS) $? | $P
- X touch $@
- Xdistr: $(FILES)
- X (echo relaynews update of `date`; echo ""; bundle $?) | /bin/mail cnews-updates
- X touch $@
- Xclean:
- X rm -f core a.out relaynews *.o $(POSSDEPFILES)
- X
- X# header dependencies follow
- Xactive.o: active.h ../include/news.h ../include/newspaths.h
- Xcaches.o: ../include/news.h
- Xcheckdir.o: ../include/news.h
- Xcontrol.o: ../include/news.h ../include/newspaths.h headers.h history.h
- Xfileart.o: ../include/news.h ../include/newspaths.h active.h headers.h system.h
- Xheaders.o: ../include/news.h headers.h
- Xhistory.o: ../include/news.h ../include/newspaths.h headers.h
- Xhostname.o: ../include/news.h ../include/newspaths.h
- Xio.o: ../include/news.h
- Xmsgs.o: ../include/news.h
- Xprocart.o: ../include/news.h active.h headers.h system.h
- Xrelaynews.o: ../include/news.h ../include/newspaths.h active.h cpu.h headers.h system.h
- Xstring.o: ../include/news.h
- Xsys.o: ../include/news.h ../include/newspaths.h system.h
- Xtransmit.o: ../include/news.h ../include/newspaths.h headers.h system.h
- END_OF_FILE
- if test 3080 -ne `wc -c <'rnews/makefile'`; then
- echo shar: \"'rnews/makefile'\" unpacked with wrong size!
- fi
- # end of 'rnews/makefile'
- fi
- if test -f 'rnews/speed/mem/active.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rnews/speed/mem/active.c'\"
- else
- echo shar: Extracting \"'rnews/speed/mem/active.c'\" \(3682 characters\)
- sed "s/^X//" >'rnews/speed/mem/active.c' <<'END_OF_FILE'
- X/*
- X * active file access functions (in-memory version)
- X * TODO: use hashing for speed & to eliminate MAXNGS
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "news.h"
- X
- X#define MAXNGS 2000
- X
- Xstatic FILE *fp = NULL;
- Xstatic char filerelname[] = "active";
- Xstatic char *active = NULL; /* points at entire active file */
- Xstatic int actsize; /* bytes in active: type int determined by fread */
- Xstatic unsigned artlines; /* lines in artlnps actually used */
- X/* TODO: make this a linked list to avoid the MAXNGS limit? */
- Xstatic char *artlnps[MAXNGS]; /* point at lines in active file */
- X
- X/* TODO: make these two macros in a header file? */
- Xlong
- Xnxtartnum(ng)
- Xchar *ng;
- X{
- X long incartnum();
- X
- X return incartnum(ng, 1);
- X}
- X
- Xlong
- Xprevartnum(ng)
- Xchar *ng;
- X{
- X long incartnum();
- X
- X return incartnum(ng, -1);
- X}
- X
- Xstatic long
- Xincartnum(ng, inc)
- Xchar *ng;
- Xint inc;
- X{
- X register int nglen = strlen(ng);
- X register char *pos;
- X register unsigned line = 0;
- X register long nextart = -1;
- X char artnumstr[ARTNUMWIDTH + 1];
- X extern char ldzeropad[];
- X char *sprintf(), *strncpy();
- X long atol();
- X
- X if (artload() != ST_OKAY)
- X return nextart;
- X while (pos = artlnps[line], line++ < artlines && pos[0] != '\0')
- X if (STREQN(pos, ng, nglen) && pos[nglen] == ' ') {
- X nextart = atol(&pos[nglen + 1]) + inc;
- X (void) sprintf(artnumstr, ldzeropad,
- X ARTNUMWIDTH, ARTNUMWIDTH, nextart);
- X (void) strncpy(&pos[nglen + 1], artnumstr, ARTNUMWIDTH);
- X break;
- X }
- X return nextart;
- X}
- X
- Xint
- Xartload() /* reload any cached data */
- X{
- X int status = 0;
- X char *libfile();
- X FILE *fopenwclex();
- X
- X if (fp == NULL)
- X if ((fp = fopenwclex(libfile(filerelname), "r+")) == NULL)
- X status |= ST_DROPPED;
- X if (fp != NULL && active == NULL) { /* file open, no cache */
- X struct stat sb;
- X char *malloc();
- X
- X if (fstat(fileno(fp), &sb) < 0)
- X warning("can't fstat %s", libfile(filerelname));
- X else if (actsize = sb.st_size, /* squeeze into an int */
- X (unsigned)actsize != sb.st_size)
- X warning("%s won't fit into memory", libfile(filerelname));
- X else if ((active = malloc((unsigned)actsize+1)) == NULL)
- X warning("can't allocate memory for %s", libfile(filerelname));
- X else {
- X rewind(fp);
- X /* TODO: read with fgets to avoid linescan() */
- X if (fread(active, 1, actsize, fp) != actsize) {
- X warning("error reading %s", libfile(filerelname));
- X free(active);
- X active = NULL;
- X } else {
- X active[actsize] = '\0'; /* make a proper string */
- X if ((artlines = linescan(active, artlnps,
- X MAXNGS)) >= MAXNGS) {
- X extern char *progname;
- X
- X (void) fprintf(stderr,
- X "%s: too many newsgroups in %s\n",
- X progname, libfile(filerelname));
- X free(active);
- X active = NULL;
- X }
- X }
- X }
- X if (active == NULL)
- X status |= ST_DROPPED; /* give up! */
- X }
- X return status;
- X}
- X
- Xint
- Xartsync() /* sync to disk any cached data */
- X{
- X int status = 0;
- X char *libfile();
- X
- X if (fp != NULL) {
- X rewind(fp);
- X if (active != NULL && fwrite(active, actsize, 1, fp) != 1) {
- X warning("error writing %s", libfile(filerelname));
- X status |= ST_DROPPED;
- X }
- X if (fclose(fp) == EOF)
- X status |= ST_DROPPED;
- X }
- X fp = NULL;
- X if (active != NULL)
- X free(active); /* give back memory active used */
- X active = NULL;
- X return status;
- X}
- X
- X/*
- X * Store in lnarray the addresses of the starts of lines in s.
- X * Return the number of lines found; if greater than nent,
- X * store only nent and return nent.
- X */
- Xint
- Xlinescan(s, lnarray, nent)
- Xregister char *s;
- Xregister char **lnarray;
- Xregister int nent;
- X{
- X register int i = 0;
- X register char *nlp = s;
- X char *index();
- X
- X if (i < nent)
- X lnarray[i++] = s;
- X while (i < nent && (nlp = index(nlp, '\n')) != NULL)
- X lnarray[i++] = ++nlp;
- X return i;
- X}
- END_OF_FILE
- if test 3682 -ne `wc -c <'rnews/speed/mem/active.c'`; then
- echo shar: \"'rnews/speed/mem/active.c'\" unpacked with wrong size!
- fi
- # end of 'rnews/speed/mem/active.c'
- fi
- if test -f 'rnews/speed/mem/sys.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rnews/speed/mem/sys.c'\"
- else
- echo shar: Extracting \"'rnews/speed/mem/sys.c'\" \(4014 characters\)
- sed "s/^X//" >'rnews/speed/mem/sys.c' <<'END_OF_FILE'
- X/*
- X * inews sys file reading functions (in-memory version)
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "news.h"
- X#include "system.h"
- X
- Xstatic FILE *fp = NULL; /* descriptor for libfile("sys") */
- Xstatic char filerelname[] = "sys";
- Xstatic char defaultcmd[] = "exit 1"; /* reminder to bozo admins */
- Xstatic struct system *firstsys = NULL; /* cache */
- Xstatic struct system *currsys = NULL; /* current system */
- X
- Xstruct system *
- Xoursys() /* return our sys entry */
- X{
- X register struct system *sys;
- X static struct system fakesys;
- X char *hostname();
- X struct system *nextsys();
- X
- X rewsys();
- X while ((sys = nextsys()) != NULL && !STREQ(sys->sy_name, hostname()))
- X ;
- X if (sys == NULL) { /* no entry; cook one up */
- X fakesys.sy_name = hostname();
- X fakesys.sy_ngs = "all";
- X fakesys.sy_flags = 0;
- X fakesys.sy_lochops = 0;
- X fakesys.sy_cmd = defaultcmd;
- X fakesys.sy_next = NULL;
- X sys = &fakesys;
- X }
- X return sys;
- X}
- X
- X/*
- X * Returned pointer points at a static struct whose members
- X * point at static storage.
- X */
- Xstruct system *
- Xnextsys() /* return next sys entry */
- X{
- X struct system *retsys;
- X char *libfile();
- X FILE *fopenwclex();
- X
- X if (firstsys == NULL && fp == NULL)
- X if ((fp = fopenwclex(libfile(filerelname), "r")) == NULL)
- X return NULL;
- X if (fp != NULL && firstsys == NULL) /* file open, no cache */
- X readsys(); /* read & parse fp */
- X retsys = currsys; /* save current ptr. */
- X if (currsys != NULL)
- X currsys = currsys->sy_next; /* advance current ptr. */
- X return retsys;
- X}
- X
- Xrewsys()
- X{
- X currsys = firstsys;
- X}
- X
- Xstatic char *curr, *next; /* parsing state */
- X
- Xstatic
- Xreadsys()
- X{
- X char sysline[MAXLINE];
- X
- X rewind(fp);
- X /* TODO: write & use cfgets to read continued lines (need bigger MAXLINE) */
- X while (fgets(sysline, sizeof sysline, fp) != NULL)
- X if (sysline[0] != '#' && sysline[0] != '\n') { /* not a comment */
- X register struct system *sysp;
- X char *flagstring;
- X char *malloc();
- X
- X sysp = (struct system *)malloc(sizeof *sysp);
- X if (sysp == NULL)
- X errunlock("out of memory for system structs", "");
- X
- X /* parse into sysp */
- X trim(sysline);
- X next = sysline;
- X parse(&sysp->sy_name);
- X parse(&sysp->sy_ngs);
- X parse(&flagstring);
- X parse(&sysp->sy_cmd);
- X /* could check for extra fields here */
- X sysp->sy_flags = flgtobits(flagstring);
- X sysp->sy_lochops = 0; /* Ln value someday */
- X free(flagstring); /* malloced by parse */
- X sysp->sy_next = NULL;
- X
- X /* fill in any defaults */
- X if (sysp->sy_cmd[0] == '\0') {
- X free(sysp->sy_cmd); /* malloced by parse */
- X sysp->sy_cmd = defaultcmd; /* NB not malloced */
- X }
- X
- X /* stash *sysp away on the tail of the current list */
- X if (firstsys == NULL)
- X firstsys = sysp; /* 1st system */
- X else
- X currsys->sy_next = sysp; /* tack on tail */
- X currsys = sysp;
- X }
- X (void) fclose(fp); /* file no longer needed */
- X fp = NULL; /* mark file closed */
- X rewsys();
- X}
- X
- Xparse(into)
- Xregister char **into;
- X{
- X char *strsave(), *parsecolon();
- X
- X curr = next;
- X if (curr == NULL)
- X *into = strsave("");
- X else {
- X next = parsecolon(curr);
- X *into = strsave(curr);
- X }
- X if (*into == NULL)
- X errunlock("out of memory for sys strings", "");
- X}
- X
- Xchar *
- Xparsecolon(line) /* return NULL or ptr. to byte after colon */
- Xchar *line;
- X{
- X register char *colon;
- X
- X INDEX(line, ':', colon);
- X if (colon != NULL)
- X *colon++ = '\0'; /* turn colon into a NUL */
- X return colon;
- X}
- X
- Xstatic int
- Xflgtobits(s)
- Xregister char *s;
- X{
- X register int bits = 0;
- X
- X for (; *s != '\0'; s++)
- X switch (*s) {
- X case 'A':
- X errunlock("A news format not supported", "");
- X /* NOTREACHED */
- X case 'B': /* mostly harmless */
- X break;
- X case 'F':
- X bits |= FLG_BATCH;
- X break;
- X case 'L':
- X bits |= FLG_LOCAL;
- X /* TODO: parse Ln, but maybe not here */
- X break;
- X case 'N':
- X bits |= FLG_IHAVE;
- X errunlock("N flag given but I-have/send-me is not supported", "");
- X /* NOTREACHED */
- X case 'U':
- X bits |= FLG_PERM;
- X break;
- X default:
- X errunlock("unknown sys flag `%s' given", s);
- X /* NOTREACHED */
- X }
- X return bits;
- X}
- END_OF_FILE
- if test 4014 -ne `wc -c <'rnews/speed/mem/sys.c'`; then
- echo shar: \"'rnews/speed/mem/sys.c'\" unpacked with wrong size!
- fi
- # end of 'rnews/speed/mem/sys.c'
- fi
- echo shar: End of archive 6 \(of 14\).
- ## End of shell archive.
- exit 0
-